import { DatabaseManager } from './DatabaseManager';
import { DatabaseEncryptionOptions } from '../types';
import Database from 'better-sqlite3';

/**
 * 数据库加密管理器
 */
export class DatabaseEncryptionManager {

  // 是否支持加密
  private static _encryptionSupported: boolean | null = null;

  constructor(private db: DatabaseManager) {
  }

  /**
   * 检查系统是否支持加密
   * @returns 是否支持加密
   */
  public isSupported(): boolean {
    return DatabaseEncryptionManager.isEncryptionSupported();
  }

  /**
   * 检查系统是否支持加密
   * @returns 是否支持加密
   */
  public static isEncryptionSupported(): boolean {
    if (this._encryptionSupported !== null) {
      return this._encryptionSupported;
    }

    try {
      // 尝试动态导入better-sqlite3-multiple-ciphers
      // eslint-disable-next-line @typescript-eslint/no-var-requires
      require('better-sqlite3-multiple-ciphers');
      this._encryptionSupported = true;
    } catch (error) {
      console.info('better-sqlite3-multiple-ciphers未安装，加密功能不可用');
      this._encryptionSupported = false;
    }

    return this._encryptionSupported;
  }

  /**
   * 安全地设置数据库密钥
   * @param database 数据库实例
   * @param password 密码（不会被存储）
   */
  public setKey(database: Database.Database, password: string): void {
    if (!this.isSupported()) {
      throw new Error('加密功能需要安装better-sqlite3-multiple-ciphers库');
    }
    
    // 设置密钥
    database.pragma(`key='${password}'`);
  }

  /**
   * 使用密码加密数据库
   * @param options 加密选项（密码不会被存储）
   * @returns DatabaseEncryptionManager实例，支持链式调用
   */
  public encrypt(options: DatabaseEncryptionOptions): DatabaseEncryptionManager {
    if (!this.isSupported()) {
      throw new Error('加密功能需要安装better-sqlite3-multiple-ciphers库');
    }
    
    const database = this.db.getDatabase();
    database.pragma(`rekey='${options.password}'`);
    
    return this;
  }

  /**
   * 解密数据库，移除密码保护
   * @returns DatabaseEncryptionManager实例，支持链式调用
   */
  public decrypt(): DatabaseEncryptionManager {
    if (!this.isSupported()) {
      throw new Error('加密功能需要安装better-sqlite3-multiple-ciphers库');
    }
    
    const database = this.db.getDatabase();
    database.pragma(`rekey=''`);
    return this;
  }

  /**
   * 更改数据库密码
   * @param options 新的加密选项（密码不会被存储）
   * @returns DatabaseEncryptionManager实例，支持链式调用
   */
  public changePassword(options: DatabaseEncryptionOptions): DatabaseEncryptionManager {
    return this.encrypt(options);
  }
}
